export interface IColorObj {
    r: number;
    g: number;
    b: number;
    a?: number;
}

/**
 * 255颜色值转16进制颜色值
 * @param n 255颜色值
 * @returns hex 16进制颜色值
 */
export const toHex = (n: number) => `${n > 15 ? '' : 0}${n.toString(16)}`;

/**
 * 颜色对象转化为16进制颜色字符串
 * @param colorObj 颜色对象
 */
export const toHexString = (colorObj: IColorObj) => {
    const { r, g, b, a = 1 } = colorObj;
    return `#${toHex(Math.round(r))}${toHex(Math.round(g))}${toHex(Math.round(b))}${a === 1 ? '' : toHex(Math.floor(a * 255))}`;
};

/**
 * 颜色对象转化为rgba颜色字符串
 * @param colorObj 颜色对象
 */
export const toRgbaString = (colorObj: IColorObj) => {
    const { r, g, b, a = 1 } = colorObj;
    return `rgba(${r},${g},${b},${a})`;
};

/**
 * 16进制颜色字符串解析为颜色对象
 * @param color 颜色字符串
 * @returns IColorObj
 */
export const parseHexColor = (color: string): IColorObj => {
    let hex = color.slice(1);
    let a = 1;
    if (hex.length === 3) {
        hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
    }
    if (hex.length === 8) {
        a = parseInt(hex.slice(6), 16) / 255;
        hex = hex.slice(0, 6);
    }
    const bigint = parseInt(hex, 16);
    return {
        r: (bigint >> 16) & 255,
        g: (bigint >> 8) & 255,
        b: bigint & 255,
        a,
    } as IColorObj;
};

/**
 * rgba颜色字符串解析为颜色对象
 * @param color 颜色字符串
 * @returns IColorObj
 */
export const parseRgbaColor = (color: string): IColorObj => {
    const arr = color.match(/(\d(\.\d+)?)+/g) || [];
    const res = arr.map((s: string) => parseInt(s, 10));
    return {
        r: res[0],
        g: res[1],
        b: res[2],
        a: parseFloat(arr[3]),
    } as IColorObj;
};

/**
 * HSL颜色字符串解析为颜色对象
 * @param color 颜色字符串
 * @returns IColorObj
 */
export const parseHSLColor = (color: string): IColorObj => {
    let [h, s, l, a = 1] = color.match(/(\d(\.\d+)?)+/g).map(item => Number(item))
    s /= 100;
    l /= 100;
    const k = (n) => (n + h / 30) % 12;
    const f = (n) => l - s * Math.min(l, 1 - l) * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
    return {
        r: 255 * f(0),
        g: 255 * f(8),
        b: 255 * f(4),
        a,
    } as IColorObj;
};

/**
 * 颜色字符串解析为颜色对象
 * @param color 颜色字符串
 * @returns IColorObj
 */
export const parseColorString = (color: string) => {
    if (color.startsWith('#')) {
        return parseHexColor(color);
    } else if (color.startsWith('rgb')) {
        return parseRgbaColor(color);
    } else if (color.startsWith('hsla')) {
        return parseHSLColor(color);
    } else if (color === 'transparent') {
        return parseHexColor('#00000000');
    }
    throw new Error(`color string error: ${color}`);
};